/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @Title: RxUtil
 * @Package com.rx.core.util
 * @Description: 全局工具类
 * @author: 陈锦韬
 * @date: 2020\4\19 0019
 * @version V1.0
 * @Copyright: 2020 陈锦韬  All rights reserved.
 */
package com.rx.core.util;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rx.core.base.*;
import com.rx.core.dbase.RxMarkDbMust;
import com.rx.core.enm.RESULT_CODE;
import com.rx.core.enm.RX_LOG_MODE;
import com.rx.core.iface.*;
import com.rx.core.service.handlerMode;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author: Administrator
 * @Description: 全局工具类
 * @date: 2020\4\19 0019
 */
@Slf4j
public class RxUtil {


    private static Pattern humpPattern = Pattern.compile("[A-Z]");

    private static String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            try{
                Object srcValue = src.getPropertyValue(pd.getName());
                if (srcValue == null) {
                    emptyNames.add(pd.getName());
                }
            }catch (Exception e){

            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    public static void copyProperties(Object src, Object target){
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
    }


    public static class ConvertUtil{
        /**
         * 对象转换
         * @param object
         * @param cls
         * @return
         */
        public static Object objectConvert(Object object , Class<?> cls){
            if (EmptyChecker.isEmpty(object)){
                return object;
            }
            return JSON.parseObject(JSON.toJSONString(object),cls);
        }
        public static Object arrayConvert(Object object , Class<?> cls){
            if (EmptyChecker.isEmpty(object)){
                return object;
            }
            return JSON.parseArray(JSON.toJSONString(object),cls);
        }

        /**
         * 深拷贝
         * @param object
         * @return
         */
        public static Object deepCopy(Object object){
            if (EmptyChecker.isEmpty(object)){
                return object;
            }
            return objectConvert(object,object.getClass());
        }
    }

    public static class CheckUtil{
        public static void check(Object object, RxResultCode rxResultCode){
            if(EmptyChecker.isEmpty(object)){
                log.error("\n========校验异常:["+rxResultCode.getCode()+"]"+rxResultCode.getDesc());
                throw new RxBaseException(rxResultCode);
            }
        }
        public static void check(Object object,RxResultCode rxResultCode, Object... argArray){
            if(EmptyChecker.isEmpty(object)){
                log.error("\n========校验异常:["+rxResultCode.getCode()+"]"+String.format(rxResultCode.getDesc(),argArray));
                throw new RxBaseException(rxResultCode,argArray);
            }
        }
        public static void checkResult(Object object,RxResultCode rxResultCode, Object... argArray){
            if(EmptyChecker.isEmpty(object)){
                log.error("\n========校验异常:["+rxResultCode.getCode()+"]"+String.format(rxResultCode.getDesc(),argArray));
                throw new RxBaseException(rxResultCode,argArray);
            }
            if(object instanceof RxResponse){
                RxResponse rxResponse = (RxResponse)object;
                if (!RESULT_CODE.OK.getCode().equalsIgnoreCase(rxResponse.getResultCode())){
                    log.error(RX_LOG_MODE.ERROR.getFormat("返回结果失败：{}，{}"),rxResponse.getResultCode(),rxResponse.getResultMessage());
                    throw new RxBaseException(rxResponse.getResultCode(),rxResponse.getResultMessage());
                }
                if(EmptyChecker.isEmpty(rxResponse.getResultData())){
                    log.error(RX_LOG_MODE.ERROR.getFormat("返回结果为空"));
                    throw new RxBaseException(rxResultCode,argArray);
                }
            }
        }
        public static void condition(boolean yes, RxResultCode rxResultCode){
            if(yes){
                log.error("\n========校验异常:["+rxResultCode.getCode()+"]"+rxResultCode.getDesc());
                throw new RxBaseException(rxResultCode);
            }
        }
        public static void condition(boolean yes,RxResultCode rxResultCode, Object... argArray){
            if(yes){
                log.error("\n========校验异常:["+rxResultCode.getCode()+"]"+String.format(rxResultCode.getDesc(),argArray));
                throw new RxBaseException(rxResultCode,argArray);
            }
        }
        public static void throwOut(RxResultCode rxResultCode, Object... argArray){
            log.error("\nRX [抛出异常]:["+rxResultCode.getCode()+"]"+String.format(rxResultCode.getDesc(),argArray));
            throw new RxBaseException(rxResultCode,argArray);
        }
        public static void dealThrowable(Throwable e){
            if(e instanceof InvocationTargetException){
                Throwable throwable = ((InvocationTargetException) e).getTargetException();
                if (throwable instanceof RxBaseException){
                    throw (RxBaseException)throwable;
                }
                if(throwable instanceof SQLIntegrityConstraintViolationException){
                    throwOut(RESULT_CODE.ERR_SQL_OPER,"数据库失败:"+throwable.getMessage());
                }
                throwOut(RESULT_CODE.MESSAGE,"处理器失败:"+throwable.getMessage());
            }
            if(e.getCause() instanceof SQLIntegrityConstraintViolationException){
                String message = e.getCause().getMessage();
                if (EmptyChecker.notEmpty(message)){
                    if(message.contains("Duplicate entry") && message.contains("USER_UNIQUE")){
                        message = "该用户已经存在,请重新输入用户名";
                        throwOut(RESULT_CODE.MESSAGE,message);
                    }
                }
                throwOut(RESULT_CODE.ERR_SQL_OPER,message);
            }
            if(e instanceof RxBaseException){
               throw (RxBaseException)e;
            }
            throwOut(RESULT_CODE.MESSAGE,"处理器失败:"+e.getMessage());
        }
    }
    public static Object notNullDo(Object object, NotNullMode notNullMode){
        if(EmptyChecker.notEmpty(object)){
            notNullMode.handle(object);
        }
        return object;
    }
    public static Object nullDo(Object object, NotReturnMode notReturnMode){
        if(EmptyChecker.isEmpty(object)){
            notReturnMode.handle();
        }
        return object;
    }
    public static Object ofNull(Object obj1,Object obj2){
        if(EmptyChecker.isEmpty(obj1)){
            return obj2;
        }
        return obj1;
    }

    public static BigDecimal ofZero(BigDecimal obj1,BigDecimal obj2){
        if(EmptyChecker.isEmpty(obj1)){
            return obj2;
        }
        if (BigDecimal.ZERO.compareTo(obj1) ==0){
            return obj2;
        }
        return obj1;
    }
    public static void yesDo(boolean canDo, handlerMode handlerWraper){
        if(canDo){
            handlerWraper.handle();
        }
    }
    public static void tryDo(TryMode handlerWraper){
        try {
            handlerWraper.handle();
        } catch (Throwable e) {
            log.error(RX_LOG_MODE.ERROR.getFormat(" 异常不处理{}"),e.getMessage());
        }
    }
    public static class StringUtil{
        /**
         * 首字母大写
         * @param name
         * @return
         */
        public static String firstUpper(String name) {
            name = name.substring(0, 1).toUpperCase() + name.substring(1);
            return  name;
        }
        public static String firstLower(String name) {
            name = name.substring(0, 1).toLowerCase() + name.substring(1);
            return  name;
        }

        public static StringBuilder catByArray(String[] fields){
            StringBuilder stringBuilder = new StringBuilder(fields[0]);
            for (int i = 1;i < fields.length;i++) {
                stringBuilder.append(firstUpper(fields[i]));
            }
            return stringBuilder;
        }
        public static StringBuilder toHump(String noHump,String split){
            if (EmptyChecker.isEmpty(noHump)){
                return new StringBuilder();
            }

            String[] noHumpFields = noHump.toLowerCase().split(split);
            if(noHumpFields.length <=1 && !noHump.contains(split)){
                return new StringBuilder(noHump);
            }
            return catByArray(noHumpFields);
        }
        public static StringBuilder fromHump(String hump,String split){
            Matcher matcher = humpPattern.matcher(hump);
            StringBuffer sb = new StringBuffer();
            while (matcher.find()) {
                matcher.appendReplacement(sb, split + matcher.group(0).toLowerCase());
            }
            matcher.appendTail(sb);
            return new StringBuilder(sb);
        }
        /**
         * 横杠转驼峰
         * @param dash
         * @return
         */
        public static String dashToHump(String dash){
            return toHump(dash,"-").toString();
        }
        public static String dashToFirstUpperHump(String dash){
            return firstUpper(toHump(dash,"-").toString());
        }
        /**
         * 下划线转驼峰
         * @param line
         * @return
         */
        public static String lineToHump(String line){
            return toHump(line,"_").toString();
        }

        /**
         * 驼峰转下划线
         * @param hump
         * @return
         */
        public static String humpToLine(String hump){
            return fromHump(hump,"_").toString();
        }

        public static String firstUpperHumpToLine(String hump){
            return fromHump(firstLower(hump),"_").toString();
        }

        /**
         * 驼峰转横杠
         * @param hump
         * @return
         */
        public static String humpToDash(String hump){
            return fromHump(hump,"-").toString();
        }
        public static String firstUpperHumpToDash(String hump){
            return fromHump(firstLower(hump),"-").toString();
        }

        /**
         * 横杠转下划线
         * @param dash
         * @return
         */
        public static String dashToLine(String dash){
            return dash.replace('-','_');
        }
        public static String lineToDash(String line){
            return line.replace('_','-');
        }
    }
    public static class ListUtil{
        /**
         * 获取列表最后一个
         * @param list
         * @return
         */
        public static Object getLast(List list){
            if(EmptyChecker.isEmpty(list)){
                return null;
            }
            return list.get(list.size() - 1);
        }

        /**
         * 获取列表第一个
         * @param list
         * @return
         */
        public static Object getFirst(List list){
            if(EmptyChecker.isEmpty(list)){
                return null;
            }
            return list.get(0);
        }
        public static Object onlyOne(List list,String message){
            RxUtil.CheckUtil.check(list,RESULT_CODE.MESSAGE,message);

            RxUtil.CheckUtil.condition(1 != list.size(),RESULT_CODE.MESSAGE,message);

            return list.get(0);
        }
        public static List notNullList(List list){
            if(EmptyChecker.isEmpty(list)){
                return Collections.emptyList();
            }
            return list;
        }

        public static List merge(List list, List subList){
            if(EmptyChecker.isEmpty(subList)){
                return list;
            }
            list.addAll(subList);
            return list;
        }

        private static boolean hasInList(TreeNode treeChildNode,List list){
            for (Object child : list) {
                TreeNode childItem = (TreeNode)child;
                if (treeChildNode.code().equals(childItem.code())) {
                    return true;
                }
            }
            return false;
        }
        private static Iterator<TreeNode> addChildNode(List list,TreeNode treeNode){
            Iterator<TreeNode> iterator = list.iterator();
            while (iterator.hasNext()) {
                TreeNode treeChildNode = iterator.next();
                if (treeChildNode.parentCode().equals(treeNode.code())) {
                    if (!hasInList(treeChildNode,treeNode.childList())) {
                        treeNode.childList().add(treeChildNode);
                        // iterator.remove();
                    }
                }
            }
            return null;
        }
        private static List listToTreeRound(List<TreeNode> list,String parentCode){
            List<TreeNode> trees = new ArrayList<>();
            Iterator<TreeNode> iterator = list.iterator();
            while (iterator.hasNext()) {
                // 获取到根节点
                TreeNode treeNode = iterator.next();
                if (EmptyChecker.notEmpty(treeFindByCode(trees,treeNode.code()))) {
                    iterator.remove();
                }
                if (parentCode.equals(treeNode.parentCode())) {
                    trees.add(treeNode);
                    iterator.remove();
                }

                // 遍历获取所有节点下的子节点数据，去除子节点列表中的重复数据
                addChildNode(list,treeNode);
            }
            return trees;
        }

        /**
         * code 注意：需要严格编码。子节点包含父节点编码。位数不足以0补充
         * @param list
         * @param parentCode
         * @return
         */
        public static List listToTree(List<TreeNode> list,String parentCode){

            list = list.stream().sorted(Comparator.comparing(TreeNode::code)).collect(Collectors.toList());
            if(EmptyChecker.isEmpty(parentCode)){
                parentCode = ((TreeNode)getFirst(list)).parentCode();
            }
            List<TreeNode> trees = listToTreeRound(list,parentCode);
            while (list.size() > 0){
                // 散列不成树
                List<TreeNode> otherList = listToTreeRound(list,((TreeNode)getFirst(list)).parentCode());
                trees.addAll(otherList);
            }
            return trees;
        }
        public static TreeNode treeFindByCode(List<TreeNode> trees,String code){
            TreeNode treeNode = null;
            if(EmptyChecker.isEmpty(trees)||EmptyChecker.isEmpty(code)){
                return treeNode;
            }
            for (TreeNode tree : trees) {
                if(code.equalsIgnoreCase(tree.code())){
                    return tree;
                }// 去掉末尾的多个0 。 为了解决 4110 误以为是 4111的子节点。需要反过来判断。
                if(!code.startsWith(tree.code().replaceAll("0+$", ""))){
                    continue;
                }
                treeNode = treeFindByCode(tree.childList(),code);
                //　如果为空。继续寻找
                if(EmptyChecker.notEmpty(treeNode)){
                    return treeNode;
                }
            }
            return treeNode;
        }
        public static List treeToList(TreeNode node){

            List<TreeNode> list = node.childList();
            if(EmptyChecker.isEmpty(list)){
                return new ArrayList();
            }
            List<TreeNode> returnList = new ArrayList<>();
            for (TreeNode treeNode : list) {
               List childList = treeToList(treeNode);
               if (EmptyChecker.notEmpty(childList)){
                   returnList.addAll(childList);
               }
               returnList.add(treeNode);
            }
            return returnList;
        }
        // 从子树中获取所有下级节点的列表
        public static List treeToChildList(TreeNode root,TreeNode node){
            if(root == null || node == null){
                return new ArrayList();
            }
            if (root.code() .equalsIgnoreCase(node.code()) ){
                return treeToList(root);
            }
            if(EmptyChecker.isEmpty(root.childList())){
                return new ArrayList();
            }
            for (TreeNode treeNode : root.childList()) {
                List childList = treeToChildList(treeNode,node);
                if (EmptyChecker.notEmpty(childList)){
                    // 找到节点立刻返回。
                    return childList;
                }
            }
            return  new ArrayList<>();
        }
    }

    public static class Reflection{

        public static List<Field> getAllField(Class cls,Class anno,boolean needSuperclass){
            if(Object.class.equals(cls)){
                return Collections.emptyList();
            }
            Field[] fields = cls.getDeclaredFields();
            if(EmptyChecker.isEmpty(fields)){
                return Collections.emptyList();
            }
            List<Field> resultList = new ArrayList<>();
            for (Field field : fields) {
                if (EmptyChecker.isEmpty(anno)){
                    resultList.add(field);
                    continue;
                }
                if (EmptyChecker.notEmpty(field.getDeclaredAnnotation(anno))){
                    resultList.add(field);
                }
            }
            if (needSuperclass){
                resultList.addAll(getAllField(cls.getSuperclass(),anno,true));
            }
            return resultList;
        }
        public static List<Field> getAllField(Class cls){
            return getAllField(cls,null,true);
        }

        public static List<Field> getFieldList(Class cls,Class anno){
            return getAllField(cls,anno,false);
        }

        public static Object getFieldValue(Object object,Field field){
            field.setAccessible(true);
            try {
                return field.get(object);
            } catch (IllegalAccessException e) {
                log.error(RX_LOG_MODE.DEFAULT.getFormat("{}"),"字段获取失败",e.getMessage());
            }
            return null;
        }
        public static void setFieldValue(Object object,Field field,Object value){
            field.setAccessible(true);
            try {
                field.set(object,value);
            } catch (IllegalAccessException e) {
                log.error(RX_LOG_MODE.DEFAULT.getFormat("{}"),"字段获取失败",e.getMessage());
            }
        }

        public static void setFieldValue(Object object,String field,Object value){
            try {
                Field fieldObj = getField(object.getClass(),field);
                setFieldValue(object,fieldObj,value);
            } catch (NoSuchFieldException e) {
                return;
            }
        }

        public static Field getField(Class cls,String name) throws NoSuchFieldException {
            if (cls.equals(Object.class)){
                throw new NoSuchFieldException();
            }
            try {
                return cls.getDeclaredField(name);
            } catch (NoSuchFieldException e) {
                return getField(cls.getSuperclass(),name);
            }
        }

        public static void holdValue(Object object,List<String> fieldList){
            if(EmptyChecker.isEmpty(fieldList)||EmptyChecker.isEmpty(object)){
                return;
            }

            List<Field> fieldLists = getAllField(object.getClass(),null,false);
            for (Field field : fieldLists) {
                if(!fieldList.contains(field.getName())){
                    setFieldValue(object,field,null);
                }
            }
        }

        public static Object getFieldValue(Object object,String fieldName){
            try {
                Field field = getField(object.getClass(),fieldName);
                return getFieldValue(object,field);
            } catch (NoSuchFieldException e) {

            }
            return null;
        }

    }

    @Slf4j
    public static class FileUtil{
        /**将 file 转化为 Base64*/
        public static String fileToBase64(File file) {
            FileInputStream inputFile;
            try {
                inputFile = new FileInputStream(file);
                byte[] buffer = new byte[(int) file.length()];
                inputFile.read(buffer);
                inputFile.close();
                return Base64.getEncoder().encodeToString(buffer);
            } catch (Exception e) {
                throw new RuntimeException("文件路径无效\n" + e.getMessage());
            }
        }
        /**将Base64 转换为file文件*/
        public static boolean base64ToFile(String base64,File file) {
            byte[] buffer;
            try {
                buffer = Base64.getDecoder().decode(base64);

                FileOutputStream out = new FileOutputStream(file);
                out.write(buffer);
                out.close();
                return true;
            } catch (Exception e) {
                throw new RuntimeException("base64字符串异常或地址异常\n" + e.getMessage());
            }
        }


        public static ResponseEntity<FileSystemResource> export(File file) throws UnsupportedEncodingException {
            if (file == null) {
                return null;
            }
            HttpHeaders headers = new HttpHeaders();
            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
            headers.add("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getName(),"UTF-8") );
            headers.add("Pragma", "no-cache");
            headers.add("Expires", "0");
            headers.add("Last-Modified", new Date().toString());
            headers.add("ETag", String.valueOf(System.currentTimeMillis()));
            return ResponseEntity
                    .ok()
                    .headers(headers)
                    .contentLength(file.length())
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(new FileSystemResource(file));
        }
    }

    @Slf4j
    public static class EncryptUtil{
        public static String enodeBase64(byte[] bytes){
            return Base64.getEncoder().encodeToString(bytes);
        }
        public static byte[] decodeBase64(String str){
            return Base64.getDecoder().decode(str);
        }
        public static  String encodeUTF8StringBase64(String str){
            return enodeBase64(str.getBytes(StandardCharsets.UTF_8));
        }
        public static  String decodeUTF8StringBase64(String str){
            return new String(decodeBase64(str),StandardCharsets.UTF_8);
        }
        public static String encodeURL(String url){
            try {
                return URLEncoder.encode(url,"utf-8");
            } catch (UnsupportedEncodingException e) {
                log.error(RX_LOG_MODE.ERROR.getFormat("utf-8编码失败"));
            }
            return null;
        }
        public static String decodeURL(String url){
            try {
                return URLDecoder.decode(url,"utf-8");
            } catch (UnsupportedEncodingException e) {
                log.error(RX_LOG_MODE.ERROR.getFormat("utf-8解码失败"));
            }
            return null;
        }

        public static String toMD5(String text) {
            MessageDigest messageDigest = null;
            try {
                messageDigest = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                return "渣男机女";
            }
            byte[] digest = messageDigest.digest(text.getBytes());
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < digest.length; i++) {
                int digestInt = digest[i] & 0xff;
                //将10进制转化为较短的16进制
                String hexString = Integer.toHexString(digestInt);
                if (hexString.length() < 2) {
                    sb.append(0);
                }
                sb.append(hexString);
            }
            return sb.toString();
        }
    }

    @Slf4j
    public static class Amount{
        public static BigDecimal createWithDefault(String digital,BigDecimal defaultVal){
            if (EmptyChecker.isEmpty(digital)){
               return (BigDecimal)ofNull(defaultVal,BigDecimal.ZERO);
            }

            return new BigDecimal(digital);
        }
        public static BigDecimal createWithDefault(String digital,BigDecimal defaultVal,int times){
            if (EmptyChecker.isEmpty(digital)){
                return (BigDecimal)ofNull(defaultVal,BigDecimal.ZERO);
            }

            return new BigDecimal(digital).multiply(new BigDecimal(times));
        }
        public static BigDecimal createWithDefault(int digital,BigDecimal defaultVal){
            if (EmptyChecker.isEmpty(digital)){
                return (BigDecimal)ofNull(defaultVal,BigDecimal.ZERO);
            }

            return new BigDecimal(digital);
        }

        public static BigDecimal add(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return (BigDecimal)ofNull(appTwo,BigDecimal.ZERO);
            }
            return appOne.add((BigDecimal)ofNull(appTwo,BigDecimal.ZERO));
        }
        public static BigDecimal subtract(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return BigDecimal.ZERO.subtract((BigDecimal)ofNull(appTwo,BigDecimal.ZERO));
            }
            return appOne.subtract((BigDecimal)ofNull(appTwo,BigDecimal.ZERO));
        }
        public static BigDecimal multiply(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return (BigDecimal)ofNull(appTwo,BigDecimal.ZERO);
            }
            return appOne.multiply((BigDecimal)ofNull(appTwo,BigDecimal.ONE));
        }
        public static BigDecimal multiply(BigDecimal appOne,int appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return new BigDecimal(appTwo);
            }
            return appOne.multiply(new BigDecimal(appTwo));
        }
        public static BigDecimal divideRound(BigDecimal appOne,BigDecimal appTwo,int scale){
            if (EmptyChecker.isEmpty(appOne)){
                return BigDecimal.ZERO;
            }
            return appOne.divide((BigDecimal)ofZero(appTwo,BigDecimal.ONE),scale,BigDecimal.ROUND_HALF_UP);
        }

        public static BigDecimal divideRound(BigDecimal appOne,int appTwo){
            return divideRound(appOne,new BigDecimal(appTwo),2);
        }
        public static BigDecimal divideRound(BigDecimal appOne,int appTwo,int scale){
            return divideRound(appOne,new BigDecimal(appTwo),scale);
        }
        public static BigDecimal divideRound(BigDecimal appOne,BigDecimal appTwo){
            return divideRound(appOne,appTwo,2);
        }


        public static boolean bigger(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return false;
            }
            if (EmptyChecker.isEmpty(appTwo)){
                return true;
            }
            return appOne.compareTo(appTwo) > 0;
        }
        public static boolean biggerOr(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return false;
            }
            if (EmptyChecker.isEmpty(appTwo)){
                return true;
            }
            return appOne.compareTo(appTwo) >= 0;
        }

        public static boolean smaller(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return true;
            }
            if (EmptyChecker.isEmpty(appTwo)){
                return false;
            }
            return appOne.compareTo(appTwo) < 0;
        }
        public static boolean smallerOr(BigDecimal appOne,BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appOne)){
                return true;
            }
            if (EmptyChecker.isEmpty(appTwo)){
                return false;
            }
            return appOne.compareTo(appTwo) <= 0;
        }

        public static boolean smallerZero(BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appTwo)){
                return false;
            }
            return BigDecimal.ZERO.compareTo(appTwo) < 0;
        }

        public static boolean biggerZero(BigDecimal appTwo){
            if (EmptyChecker.isEmpty(appTwo)){
                return false;
            }
            return BigDecimal.ZERO.compareTo(appTwo) > 0;
        }
    }

    @Slf4j
    public static class RxDate{
        public static String data(){
            SimpleDateFormat formatter = new SimpleDateFormat(RxBaseConstant.DATE_FORMAT_DATE_NO_LINE);
            String dateString = formatter.format(new Date());
            return dateString;
        }
        public static String now(){
            SimpleDateFormat formatter = new SimpleDateFormat(RxBaseConstant.DATE_FORMAT_DATETIME);
            String dateString = formatter.format(new Date());
            return dateString;
        }
        public static Date addDays(Date d, int days){
            d.setTime(d.getTime() + days * 1000 * 60 * 60 * 24);
            return d;
        }
        public static Date afterDays(int days){
            Date d = new Date();
            d.setTime(d.getTime() + days * 1000 * 60 * 60 * 24);
            return d;
        }
        public static String afterDayString(long days,String pattern){
            Date d = new Date();
            d.setTime(d.getTime() + days * 1000 * 60 * 60 * 24);
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            String dateString = formatter.format(d);
            return dateString;
        }
    }
    /**
     * 获取UUID
     * @return
     */
    public static String getGUID()
    {
        return UUID.randomUUID().toString();
    }

    public static String toJsonString(String[] array) {
        return JSON.toJSONString(array);
    }

    public static boolean regCheck(String patternString,String string){
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(string);
        return matcher.matches();
    }

    public static List result(Object object) {
        if (object instanceof RxResponse){
            return new ArrayList<>();
        }
        if (object instanceof IPage){
            return ((IPage)object).getRecords();
        }
        return (List)object;
    }
    private static RxMarkDbMust getMainInfo(List<RxMarkDbMust> resultList, RxMarkDbMust rxMarkDbMust){
        for (RxMarkDbMust markDbMust : resultList) {
            if(markDbMust.getBid().equalsIgnoreCase(rxMarkDbMust.getBid())){
                return markDbMust;
            }
        }
        rxMarkDbMust.setDataList(new ArrayList<>());
        resultList.add(rxMarkDbMust);
        return rxMarkDbMust;
    }


    public static List<RxMarkDbMust>  assToTree(List list){

        List<RxMarkDbMust> resultList = new ArrayList<>();
        for (Object o : list) {
            RxMarkDbMust rxMarkDbMust = (RxMarkDbMust)o;

            RxMarkDbMust infoFromList =  getMainInfo(resultList,rxMarkDbMust);

            RxMarkDbMust markDbMust = (RxMarkDbMust)((RelationQuery)rxMarkDbMust).obtainRelation();
            if(EmptyChecker.notEmpty(markDbMust.getBid())){
                infoFromList.getDataList().add(markDbMust);
            }
            ((RelationQuery)rxMarkDbMust).assignRelation(null);

        }
        return resultList;
    }


    public static class SQL{
        public static void desc(RxBaseData rxBaseData,String field){
            Map<String,Object> condition = rxBaseData.conditionMap();
            // 根据插入时间进行倒叙
            condition.put("sqlOrderbydesc",field);
        }
        public static void asc(RxBaseData rxBaseData,String field){
            Map<String,Object> condition = rxBaseData.conditionMap();
            // 根据插入时间进行倒叙
            condition.put("sqlOrderbyasc",field);
        }
        public static void sum(RxBaseData rxBaseData,String field){
            Map<String,Object> condition = rxBaseData.conditionMap();
            // 根据插入时间进行倒叙
            condition.put("sqlSum",field);
        }
        public static void groupBy(RxBaseData rxBaseData,String field){
            Map<String,Object> condition = rxBaseData.conditionMap();
            // 根据插入时间进行倒叙groupby
            condition.put("sqlGroupby",field);
        }

        public static Map<String,Object> condition(RxBaseData rxBaseData){
            Map<String,Object> condition = rxBaseData.conditionMap();
            return condition;
        }
    }

    /**
     * 发送get请求
     * @param url 请求URL
     * @param param 请求参数 key:value url携带参数 或者无参可不填
     * @return
     */
    public static String doGet(String url, Map<String, String> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                //e.printStackTrace();
            }
        }
        return resultString;
    }
}
